package objects;

import gfx.Drawable;
import gfx.tiles.Tile;
import gfx.tiles.TileRenderer;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

import core.Main;
import core.Vector2;

/**
 * A drawable and tickable Bullet that damages robots when it hits them.
 * 
 * @author ruben.ortlam
 * @see core.gfx.Tickable
 * @see core.gfx.Drawable
 */
public class Bullet extends Entity {
	protected Vector2 vel;
	protected BufferedImage image;
	protected int range;
	protected double distanceTravelled;
	
	public static final int SPEED = 5;
	private static final Vector2 SIZE = new Vector2(12, 14);
	private static final int DAMAGE = 10;
	
	/**
	 * Creates a new Bullet with the given parameters.
	 * 
	 * @param pos The Position of the new Bullet
	 * @param angle The Angle of the new Bullet
	 */
	public Bullet(Vector2 pos, double angle, int range) {
		super(pos, angle, SIZE);
		this.vel = new Vector2(Math.sin(angle) * SPEED, -Math.cos(angle) * SPEED);
		this.range = range;
		this.distanceTravelled = 0;
		
		image = Main.imageLoader.load("/gfx/BOOM.png");
	}
	
	/**
	 * Contains the calculations of the Bullet for it to check if it hit anything aswell as
	 * its movement.
	 */
	@Override
	public void tick() {
		pos.add(vel);
		distanceTravelled += vel.length();
		
		if(!Main.isInWorld(pos) || distanceTravelled >= range || TileRenderer.tileCollision(pos, size) == Tile.SOLID) {
			Explosion explosion = new Explosion(new Vector2(pos), 20);
			Main.addDrawable(explosion);
			Main.addTickable(explosion);
			removed = true;
		}
		
		ArrayList<Drawable> drawables = Main.getDrawables();
		
		for(int i = 0; i < drawables.size(); i++) {
			if(drawables.get(i).getPos() != null) {
				if(drawables.get(i).getPos().distance(pos) < drawables.get(i).getSize().length() / 2) {
					if(drawables.get(i) instanceof Robot) {
						((Robot)drawables.get(i)).damage(DAMAGE);
						Explosion explosion = new Explosion(new Vector2(pos), 20);
						Main.addDrawable(explosion);
						Main.addTickable(explosion);
						removed = true;
					} else if(drawables.get(i) instanceof Mine) {
						((Mine)drawables.get(i)).trigger();
						Explosion explosion = new Explosion(new Vector2(pos), 20);
						Main.addDrawable(explosion);
						Main.addTickable(explosion);
						removed = true;
					}
				}
			}
		}
	}
	
	/**
	 * Renders the Bullet at the given Graphics.
	 * 
	 * @param g The Graphics on which the Bullet should be rendered.
	 */
	@Override
	public void render(Graphics g) {
		Graphics2D g2d = (Graphics2D)g;

		int x = (int)((pos.x - SIZE.x / 2 - Main.mapPos.x) * Main.zoom);
		int y = (int)((pos.y - SIZE.y - Main.mapPos.y) * Main.zoom);
		
		g2d.rotate(angle, x, y);
		g2d.drawImage(image, x, y, (int)(SIZE.x * Main.zoom), (int)(SIZE.y * Main.zoom), null);
		g2d.rotate(-angle, x, y);
	}
	
	@Override
	public boolean removed() {
		return removed;
	}
	
	@Override
	public Vector2 getPos() {
		return pos;
	}

	@Override
	public Color getColor() {
		return Color.BLACK;
	}

	@Override
	public Vector2 getSize() {
		return SIZE;
	}

	@Override
	public int getID() {
		return 0;
	}
}
